﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AleaBelli.Core.Data
{
    public class ContainerUnit : AbstractUnit
    {
        /// <summary>
        /// Sub units
        /// </summary>
        private List<AbstractUnit> units = new List<AbstractUnit>();

        public ContainerUnit()
        {
            units = new List<AbstractUnit>();
        }

        /// <summary>
        /// Rough meaasure of the attacking strength
        /// </summary>
        /// <returns></returns>
        internal override int DeterminePerceivedAttackingStrength(TerrainType terrain)
        {
            int strength = 0;
            foreach (AbstractUnit u in units)
            {
                strength += u.DeterminePerceivedAttackingStrength(terrain);
            }
            return strength;
        }

        /// <summary>
        /// Extract the battalions
        /// </summary>
        /// <param name="list"></param>
        internal override void GetLineBattalions(List<Battalion> list)
        {
            foreach (AbstractUnit u in units)
            {
                u.GetLineBattalions(list);
            }
        }
    }

    /// <summary>
    /// An instance of a unit
    /// </summary>
    public class Battalion : AbstractUnit
    {
        public Battalion() { }

        public Battalion(Template t) : base(t)
        {
            Strength = t.MaxStrength;
            Organization = t.MaxOrganization;
        }

        public UnitGrade UnitGrade
        {
            get;
            set;
        }

        public int Strength
        {
            get;
            set;
        }

        public int Organization
        {
            get;
            set;
        }

        /// <summary>
        /// Rough meaasure of the attacking strength
        /// </summary>
        /// <returns></returns>
        internal override int DeterminePerceivedAttackingStrength(TerrainType terrain)
        {
            // simple count of battalions for now
            return 1;
        }

        /// <summary>
        /// Extract the battalions
        /// </summary>
        /// <param name="list"></param>
        internal override void GetLineBattalions(List<Battalion> list)
        {
            list.Add(this);
        }

        /// <summary>
        /// The actual effectiveness in this terrain
        /// </summary>
        /// <param name="terrainType"></param>
        /// <returns></returns>
        internal int ActualEffectiveness(TerrainType terrainType)
        {
            return 10;
        }
    }

    /// <summary>
    /// An instance of a unit, this may consist of several sub units or a battalion
    /// </summary>
    public abstract class AbstractUnit
    {
        public AbstractUnit() { }

        public AbstractUnit(Template t) 
        {
            Id = 0; // assigned later
            Name = t.Name;
            LeaderId = 0;
            UnitSize = t.UnitSize;
            Template = t;
            ParentId = 0;
        }

        public int Id
        {
            get;
            set;
        }

        public int LeaderId
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public UnitSize UnitSize
        {
            get;
            set;
        }

        public Template Template
        {
            get;
            set;
        }

        public int ParentId
        {
            get;
            set;
        }

        /// <summary>
        /// Rough meaasure of the attacking strength
        /// </summary>
        /// <returns></returns>
        internal abstract int DeterminePerceivedAttackingStrength(TerrainType terrain);

        /// <summary>
        /// Extract the battalions
        /// </summary>
        /// <param name="list"></param>
        internal abstract void GetLineBattalions(List<Battalion> list);
    }
}
